package com.example.cheeseerpadmin.sys.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.cheeseerpadmin.sys.common.Constant;
import com.example.cheeseerpadmin.sys.common.DataGridView;
import com.example.cheeseerpadmin.sys.common.ResultObj;
import com.example.cheeseerpadmin.sys.common.TreeNode;
import com.example.cheeseerpadmin.sys.entity.SysPermission;
import com.example.cheeseerpadmin.sys.entity.SysRole;
import com.example.cheeseerpadmin.sys.service.SysPermissionService;
import com.example.cheeseerpadmin.sys.service.SysRoleService;
import com.example.cheeseerpadmin.sys.vo.RoleVo;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.util.*;

@RestController
@RequestMapping("/role")
public class RoleController {
    @Autowired
    public SysRoleService sysRoleService;

    @Autowired
    public SysPermissionService sysPermissionService;

    /**
     * 加载所有角色数据
     *
     * @param roleVo
     * @return
     */
    @RequestMapping("/loadAllRole")
    public DataGridView loadAllRole(RoleVo roleVo) {
        Page<SysRole> sysRolePage = new Page<SysRole>(roleVo.getPage(), roleVo.getLimit());

        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        sysRoleQueryWrapper.like(StringUtils.isNotBlank(roleVo.getName()), "name", roleVo.getName());
        sysRoleQueryWrapper.like(StringUtils.isNotBlank(roleVo.getRemark()), "remark", roleVo.getRemark());
        sysRoleQueryWrapper.ge(roleVo.getStartDate()!=null,"createtime",roleVo.getStartDate());
        sysRoleQueryWrapper.le(roleVo.getEndDate()!=null,"createtime",roleVo.getEndDate());

        //这里在做是否可用的查询时，我们一定要加上判断条件，否则，前端就会传一个null值给后端去进行查询，得到的信息肯定是无数据，
        sysRoleQueryWrapper.eq(roleVo.getAvailable() != null, "available", roleVo.getAvailable());
        sysRoleQueryWrapper.orderByDesc("createtime");
        Page<SysRole> page = sysRoleService.page(sysRolePage, sysRoleQueryWrapper);
        return new DataGridView(page.getTotal(), page.getRecords());
    }

    /**
     * 增加角色信息
     *
     * @param roleVo
     * @return
     */
    @RequestMapping("/addRole")
    public ResultObj addRole(RoleVo roleVo) {
        try {
            roleVo.setCreatetime(new Date());
            sysRoleService.save(roleVo);
            return ResultObj.ADD_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.ADD_ERROR;
        }
    }


    /**
     * 角色信息的更新
     *
     * @param roleVo
     * @return
     */
    @RequestMapping("/updateRole")
    public ResultObj updateRole(RoleVo roleVo) {
        try {
            sysRoleService.updateById(roleVo);
            return ResultObj.UPDATE_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.UPDATE_ERROR;
        }
    }

    /**
     * 删除角色信息
     *
     * @param id
     * @return
     */
    @RequestMapping("/deleteRoleById")
    public ResultObj deleteRoleById(Integer id) {
        try {
            sysRoleService.removeById(id);
            return ResultObj.DELETE_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.DELETE_ERROR;
        }
    }

    /**
     * 批量删除角色信息
     *
     * @param roleVo
     * @return
     */
    @RequestMapping("/batchDeleteRole")
    public ResultObj batchDeleteRole(RoleVo roleVo) {
        try {
            Collection<Serializable> idList = new ArrayList<>();
            for (Integer id : roleVo.getIds()) {
                idList.add(id);
            }
            sysRoleService.removeByIds(idList);
            return ResultObj.DELETE_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.DELETE_ERROR;
        }
    }

    /**
     *  permissionList        sys_permission数据表当中available为1的数据，也就是说可以使用的菜单后者权限全被查出来放在了这个参数当中
     *  currentRolePermission 根据角色ID在sys_role_permission表中查出来的有关权限和菜单的pid，
     *                               也就是当我们点击某个角色的分配权限时，它会用这个参数查找出来对应的权限和菜单然后存放到这个参数当中
     *  carrentPermission     这个是用来存放，根据currentRolePermission所拥有的pid
     *                               然后去到sys_permission表当中查询到id与pid对应的SysPermission数据
     * @param roleId
     * @return
     */
    @RequestMapping("/initPermissionByRoleId")
    public DataGridView initPermissionByRoleId(Integer roleId) {
        //首先查出所有可以使用的菜单和权限，也就是available=1的菜单和权限
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("available", Constant.AVAILABLE_TRUE);
        List<SysPermission> permissionList = sysPermissionService.list(queryWrapper);

        //根据角色ID查询当前角色拥有的所有的权限和菜单
        //根据查询出来的菜单ID查询权限和菜单数据
        List<Integer> currentRolePermission = sysRoleService.queryRolePermissionIdsByRid(roleId);
        List<SysPermission> carrentPermission = null;
        if (currentRolePermission.size() > 0) {
            queryWrapper.in("id", currentRolePermission);
            carrentPermission = sysPermissionService.list(queryWrapper);
        } else {
            carrentPermission = new ArrayList<>();
        }

        /**
         * 构造List<TreeNode>
         *     在permissionList的基础上，我们让得到的carrentPermission与其进行id的判断，如果相等，说明该角色拥有这个权限，那我们就
         *     让其checkArr置为1，在图形树当中的表现就是被勾选上了。
         */
        List<TreeNode> treeNodes = new ArrayList<>();
        for (SysPermission p1 : permissionList) {
            String checkArr = "0";
            for (SysPermission p2 : carrentPermission) {
                if (p1.getId() == p2.getId()) {
                    checkArr = "1";
                    break;
                }
            }
            Boolean spread = p1.getOpen() == null || p1.getOpen() == 1;
            treeNodes.add(new TreeNode(p1.getId(), p1.getPid(), p1.getTitle(), spread, checkArr));
        }
        return new DataGridView(treeNodes);
    }

    /**
     * RoleVo roleVo从前端接收到Payload数据以后，它会根据对应的属性名称进行存值，虽然前端传的是字符串，但jquery会自动拆分，id是id的值，ids是ids得值。
     * 这样，尽管前端传的是字符串，但只要属性名称是相对应的，则后端仍可以用实体对象进行接收。
     * @param roleVo
     * @return
     */
    @RequestMapping("/saveRolePermission")
    public ResultObj saveRolePermission(RoleVo roleVo) {
        try {
            sysRoleService.saveRolePermission(roleVo);
            return ResultObj.DISPATCH_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.DISPATCH_ERROR;
        }
    }
}
